package heap

import "HandWritingJVM/classfile"

type Field struct {
	ClassMember
	constValueIndex uint //若该字段为 final修饰，则其值在编译期间就可知了，可从cp中取出，因此此处存放在cp中的索引位置
	slotId          uint //字段编号
}

func (self *Field) isLongOrDouble() bool {
	return self.descriptor == "J" || self.descriptor == "D"
}

func (self *Field) copyAttributes(field *classfile.MemberInfo) {
	if valAttr := field.ConstantValueAttribute(); valAttr != nil {
		self.constValueIndex = uint(valAttr.ConstantValueIndex())
	}
}

func (self *Field) isAccessibleTo(d *Class) bool {
	if self.IsPublic() {
		return true
	}
	c := self.class
	if self.IsProtected() {
		return d == c || d.IsSubClassOf(c) ||
			c.GetPackageName() == d.GetPackageName()
	}
	return d == c
}

func newFields(class *Class, cfFields []*classfile.MemberInfo) []*Field {
	fields := make([]*Field, len(cfFields))
	for index, cfField := range cfFields {
		fields[index] = &Field{}
		fields[index].class = class
		fields[index].copyMemberInfo(cfField)
		fields[index].copyAttributes(cfField)
	}
	return fields
}

func (self *Field) IsVolatile() bool {
	return 0 != self.accessFlags&ACC_VOLATILE
}

func (self *Field) IsTransient() bool {
	return 0 != self.accessFlags&ACC_TRANSIENT
}

func (self *Field) IsEnum() bool {
	return 0 != self.accessFlags&ACC_ENUM
}

func (self *Field) ConstValueIndex() uint {
	return self.constValueIndex
}

func (self *Field) SlotId() uint {
	return self.slotId
}
